/**
*┌──────────────────────────────────────────────────────────────┐
*│　@Author：liang.xie@micro-i.com.cn
*│　@Version：1.0.0
*│　@Date：2020-11-26
*|  @Brief: 量测项目接口
*└──────────────────────────────────────────────────────────────┘
*/

#ifndef MESUREMENTINTERFACE_H
#define MESUREMENTINTERFACE_H

#include <QObject>
#include <QMetaType>
#include <QMap>
#include <QString>
#include <QPoint>

#include "E452/MeasurE452AlgBase.h"
#include "workpiecebuff.h"

#include "WorkpieceFactory.h"
#include "MeasureWorkpiece.h"

class MeasurementInterface : public QObject
{
    Q_OBJECT

public:
    MeasurementInterface(QObject *parent = nullptr);
    ~MeasurementInterface();

    struct MeasureInfo {
        float real_distance;
        float pixel_distance;
    };

    /***********************************************************************
     *  @function SetTemplatePath
     *  @brief    设置模板s_model的存放目录
     *  @param
     *  @return
    ***********************************************************************/
    bool SetTemplatePath(const std::string &path);

    /***********************************************************************
     *  @function SetStandardVal
     *  @brief    设置标准值
     *  @param
     *  @return
    ***********************************************************************/
    void SetStandardVal(const std::map<std::string, MeasureItemStandardVal> &standardValMap);

    /***********************************************************************
     *  @function SetWorkpieceInfo
     *  @brief    设置工件信息
     *  @param    modeName: 模号: "G"\"H"
     *            workpieceType: 工件类型，点检料"point"，正常料"normal"
     *  @return
    ***********************************************************************/
    void SetWorkpieceInfo(const std::string &modeName,
                          const std::string &workpieceType = "");

    /***********************************************************************
     *  @function MesurementCalRequest
     *  @brief    image buffer, deque
     *  @param    fixtureId: 0: 7号相机正常跑料xml文件 fitpara0.xml
     *                       1: 8号相机正常跑料xml文件 fitpara1.xml
     *                       2: 7号相机点检xml文件    fitpara2.xml
     *                       3: 8号相机点检xml文件    fitpara3.xml
     *  @return
    ***********************************************************************/
    void MesurementCalRequest(const QImage &image,
                              const QPoint &datumOffset,
                              int workpieceId,
                              int pictureId,
                              int channelId,
                              int fixtureId);

    /***********************************************************************
     *  @function GetDatumPixelDistance
     *  @brief    获取E452基准图像的水平、垂直像素距离
     *  @param    verPixelDistance: 垂直像素距离
     *            honPixelDistance: 水平像素距离
     *  @return   失败：false 成功： ture
    ***********************************************************************/
    bool GetDatumPixelDistance(const QImage &img,
                               int fixtureId,
                               QMap<QString, float> &pixelDistance);

signals:
    /***********************************************************************
     *  @function MesurementCalResponse
     *  @brief
     *  @param
     *  @return   measureInfo<量测项名字， 量测结果值>
     *            error: <位置，异常信息>
    ***********************************************************************/
    void MesurementCalResponse(int workpieceId,
                               int PictureId,
                               int channelId,
                               const QMap<QString, MeasureInfo>   &measureInfo, //
                               const QMap<QString, QString> &error);

public slots:
    void SlotMesurementResultResponse(int workpieceId, int pictureId, int channelId,
                                      int fixtureId,
                                   const std::map<std::string, float> &measureInfo,
                                   const QMap<QString, QString> &error);

private:
    /***********************************************************************
     *  @function MeasureWorkpiece
     *  @brief    取出可用的工件信息放到队列中
     *  @param
     *  @return
    ***********************************************************************/
//    void MeasureWorkpiece();
    cv::Mat QImageToCvMat(const QImage &image);

    /***********************************************************************
     *  @function Multimap2QMap
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
    void Map2QMap(const std::map<std::string, float> &mapInfo,
                  int fixtureId,
                       QMap<QString, MeasureInfo> &qMapInfo);

    /***********************************************************************
     *  @function   DataContraction
     *  @brief      数据收缩
     *  @param      flag: true: 数据收缩   false: 数据不收缩
     *  @return
    ***********************************************************************/
    float DataContraction(const std::string &keyStr, bool flag, float dist);


private:
    WorkpieceFactory                                m_workpieceFactory      ;
    MeasureWorkpiece                                *m_pWorkpiece           ;
    std::map<std::string, MeasureItemStandardVal>   m_measureItemStandardVal;
    bool                                            m_isDataPruning         ;
    bool                                            m_isDataXmlSwitch       ;
    // 点检工件数目，超过该工件数，自动切换正常跑料所需要的拟合参数
    int                                             m_dataCheckNum          ;
    std::string                                     m_configPath            ;

public:
    static bool                                     m_isDataCorrect         ;


};

//Q_DECLARE_METATYPE(MeasurementInterface::MeasureInfo)

#endif // MESUREMENTINTERFACE_H
